package net.wanglu.www.zzz.service.se.rcmod;

import java.util.HashMap;
import java.util.List;
import java.util.regex.Pattern;

import net.wanglu.www.zzz.service._Service;
import edu.stanford.nlp.semgraph.SemanticGraph;
import edu.stanford.nlp.semgraph.semgrex.SemgrexMatcher;
import edu.stanford.nlp.semgraph.semgrex.SemgrexPattern;
import edu.stanford.nlp.trees.EnglishGrammaticalRelations;
import edu.stanford.nlp.trees.GrammaticalRelation;
import edu.stanford.nlp.trees.Tree;
import edu.stanford.nlp.trees.TreeGraph;
import edu.stanford.nlp.trees.TreeGraphNode;
import edu.stanford.nlp.trees.TypedDependency;
import edu.stanford.nlp.trees.tregex.TregexMatcher;
import edu.stanford.nlp.trees.tregex.TregexPattern;

public class CommonRcmodExtracter extends _Service {

	@Override
	public Object service(Object... objects) throws Exception {
		// TODO Auto-generated method stub
		HashMap<?, ?> preprocessData = (HashMap<?, ?>) objects[0];
		TypedDependency rcmod = (TypedDependency) objects[1];

		List<?> tdl = (List<?>) preprocessData.get("tdl");
		Tree root = (Tree) preprocessData.get("root");
		SemanticGraph dependencies = (SemanticGraph) preprocessData.get("dependencies");
		TreeGraph treeGraph = (TreeGraph) preprocessData.get("treeGraph");
		
		TregexPattern pattern = null;
		TregexMatcher matcher = null;
		/*
		 * 先行词与其祖先
		 */
		TreeGraphNode headword = rcmod.gov();
		sb.clear();
		sb.append("/\\bNP\\b/");
		sb.append("<");
		sb.append("(");
		sb.append("/").append(Pattern.quote(headword.label().tag())).append("/");
		sb.append("<");
		sb.append("/").append(Pattern.quote(headword.label().word())).append("/");
		sb.append(")");
		pattern = TregexPattern.compile(sb.toString());
		matcher = pattern.matcher(root);
		Tree headwordAncestor = null;
		if ( matcher.find()) {
			headwordAncestor = matcher.getMatch();
		}
		/*
		 * 动词及其祖先
		 */
		TreeGraphNode verb = rcmod.dep();
		sb.clear();
		sb.append("/\\bVP\\b/");
		sb.append("<");
		sb.append("(");
		sb.append("/").append(Pattern.quote(verb.label().tag())).append("/");
		sb.append("<");
		sb.append("/").append(Pattern.quote(verb.label().word())).append("/");
		sb.append(")");	
		pattern = TregexPattern.compile(sb.toString());
		matcher = pattern.matcher(root);
		Tree verbAncestor = null;
		if ( matcher.find()) {
			verbAncestor = matcher.getMatch();
		}
		/*
		 * 关系代词及其祖先
		 */
		TreeGraphNode relativePronoun = null;
		Tree relativePronounAncestor = null;
		sb.clear();
		sb.append("{tag:/WP|WP\\$|WDT/}");
		sb.append("<<");
		sb.append("{");
		sb.append("tag:");
		sb.append(rcmod.dep().label().tag());
		sb.append(";");
		sb.append("word:");
		sb.append(rcmod.dep().label().word());
		sb.append("}");
		SemgrexPattern spattern = SemgrexPattern.compile(sb.toString());
		SemgrexMatcher smatcher = spattern.matcher(dependencies);
		String relativeTag = null, relativeWord = null;
		if ( smatcher.find()) {
			relativePronoun = treeGraph.getNodeByIndex(smatcher.getMatch().index());
			relativeTag = smatcher.getMatch().tag();
			relativeWord = smatcher.getMatch().word();
			sb.clear();
			sb.append("/WHNP/");
			sb.append("<");
			sb.append("(");
			sb.append("/").append(relativeTag).append("/");
			sb.append("<");
			sb.append("/").append(relativeWord).append("/");
			sb.append(")");
			pattern = TregexPattern.compile(sb.toString());
			matcher = pattern.matcher(root);
			if ( matcher.find()) {
				relativePronounAncestor = matcher.getMatch();
			}
		}
		/*
		 * 寻找含有rcmod节点的nsubj
		 */
		TypedDependency verbNsubj = null, headwordNsubj = null;
		for( Object obj : tdl) {
			TypedDependency TD = (TypedDependency) obj;
			GrammaticalRelation reln = TD.reln();
			if ( reln.equals(EnglishGrammaticalRelations.NOMINAL_SUBJECT) || reln.equals(EnglishGrammaticalRelations.NOMINAL_PASSIVE_SUBJECT)) {
				if ( TD.gov().toString().equals(rcmod.dep().toString())) {
					verbNsubj = TD;
				} else if ( TD.gov().toString().equals(rcmod.gov().toString()) || TD.dep().toString().equals(rcmod.gov().toString())) {
					headwordNsubj = TD;
				}
			}
		}
		
		final TreeGraphNode fheadword = headword;
		final Tree fheadwordAncestor = headwordAncestor;
		final TreeGraphNode fverb = verb;
		final Tree fverbAncestor = verbAncestor;
		final TreeGraphNode frelativePronoun = relativePronoun;
		final Tree frelativePronounAncestor = relativePronounAncestor;
		final TypedDependency fheadwordNsubj = headwordNsubj;
		final TypedDependency fverbNsubj = verbNsubj;
		
		return new _RcmodTuple() {
			{
				this.setHeadword(fheadword);
				this.setHeadwordAncestor(fheadwordAncestor);
				this.setVerb(fverb);
				this.setVerbAncestor(fverbAncestor);
				this.setRelativePronoun(frelativePronoun);
				this.setRelativePronounAncestor(frelativePronounAncestor);
				this.setHeadwordNsubj(fheadwordNsubj);
				this.setVerbNsubj(fverbNsubj);
			}
			@Override
			public Object customize() throws Exception {
				// TODO Auto-generated method stub
				return null;
			}
		};
	}
}
